import React, { useMemo, useState, Fragment } from 'react';
import Cls from 'classnames';
import { Form } from 'antd';

import './style.less';
import componentMap from './ComponentMap';

/**
 * @getLabelStyle 生成label宽度
 * @param value 宽度
 * @returns
 */
const getLabelStyle = (value: number | undefined) => {
  return {
    width: `${value}px`,
    minWidth: `${value}px`,
  };
};

/**
 * @getContentlStyle 生成内容宽度
 * @param value  宽度
 * @returns
 */
const getContentlStyle = (value: number | undefined) => {
  return {
    width: `calc(100% - ${value}px)`,
  };
};

const Descriptions: React.FC<DescriptionsAPI.Descriptions> = ({ config, ...otherFuncApi }) => {
  const { form, name, dataSource, labelWidth, headerSchema, disabled } = config;

  const [, setFormData] = useState({});

  // const descriptionData: DescriptionsAPI.FormSchema[] = useMemo(() => {
  //   return dataSource || [];
  // }, [dataSource]);

  const descriptionData: DescriptionsAPI.FormSchema[] = dataSource || [];

  const contentRender = (item: any, style?: any) => {
    const {
      field,
      required = false,
      slotRender,
      render,
      label,
      message = `请输入${label}`,
      placeholder = `请输入${label}`,
      component,
      contentAfter = null,
    } = item;

    // 根据component获取对应控件
    const Comp = componentMap.get(component);

    // 判断slotRender 是否为函数
    const isSlotRender = slotRender && typeof slotRender == 'function';

    const itemValue = form.getFieldValue(field);
    const recordValue = form.getFieldsValue();

    const props = {
      disabled: disabled,
      placeholder,
      ...item,
      style,
    };

    // DOM元素删除不识别属性
    delete props['initialValue'];
    delete props['contentAfter'];
    delete props['defaultValue'];
    return (
      <Fragment>
        {isSlotRender && component == 'Render' ? (
          slotRender(itemValue, recordValue)
        ) : render && typeof render == 'function' ? (
          <>
            <Form.Item
              name={field}
              rules={[{ required: required, message: message }]}
              initialValue={item?.initialValue}
              shouldUpdate={(_, value) => {
                setFormData(value);
                return true;
              }}
            >
              {render(itemValue, recordValue)}
            </Form.Item>
            {contentAfter != null && <div className="descriptions-item-content-anticon">{contentAfter}</div>}
          </>
        ) : (
          <>
            <Form.Item
              name={field}
              rules={[{ required: required, message: message }]}
              initialValue={item?.initialValue}
              shouldUpdate={(_, value) => {
                setFormData(value);
                return true;
              }}
            >
              <Comp {...props} />
            </Form.Item>
            {contentAfter != null && <div className="descriptions-item-content-anticon">{contentAfter}</div>}
          </>
        )}
      </Fragment>
    );
  };

  const headerRender = (headerSchema: DescriptionsAPI.FormSchema) => {
    const Comp = componentMap.get(headerSchema.component);
    const props = {
      ...headerSchema,
    };
    // DOM元素删除不识别属性
    delete props['initialValue'];
    return (
      <div className={'descriptions-container-header'}>
        <Form.Item
          name={headerSchema.field}
          rules={[{ required: headerSchema.required, message: headerSchema?.message ?? `请输入${headerSchema.label}` }]}
          initialValue={headerSchema?.initialValue}
        >
          <Comp {...props} />
        </Form.Item>
      </div>
    );
  };

  const rowRender = (items: DescriptionsAPI.FormSchema[], index: number, style?: any) => {
    return (
      <div className={'descriptions-item-row'} key={index}>
        {items.map((item) => {
          return item.component == 'Title' ? (
            <div className={Cls('descriptions-item', `descriptions-item-col-span-2`)} key={item.field}>
              <div className={'descriptions-item-label descriptions-item-title'}>
                <div style={{ width: '100%', textAlign: 'center' }}>{item.label}</div>
              </div>
            </div>
          ) : item.colSpan !== 0 ? (
            <div className={Cls('descriptions-item', `descriptions-item-col-span-${item.colSpan ?? 1}`)} key={item.field}>
              <div className={'descriptions-item-label'} style={getLabelStyle(labelWidth)}>
                <span className={item.required ? 'required' : ''}>{item.label}</span>
              </div>
              <div className={'descriptions-item-content'} style={getContentlStyle(labelWidth)}>
                {contentRender(item, style)}
              </div>
            </div>
          ) : null;
        })}
      </div>
    );
  };

  return (
    <>
      {descriptionData.length > 0 && (
        <Form form={form} name={name} key={name} {...otherFuncApi}>
          {Object.keys(headerSchema as DescriptionsAPI.FormSchema).length !== 0 && headerRender(headerSchema as DescriptionsAPI.FormSchema)}
          <div className="descriptions-container">
            {descriptionData.map((items: any, index) => {
              return rowRender(items, index, otherFuncApi?.style);
            })}
          </div>
        </Form>
      )}
    </>
  );
};

export default Descriptions;
